// 代码中存在一个潜在的死锁问题：当生产者完成任务后直接退出，没有通知消费者线程，导致消费者线程在等待缓冲区非空时永远阻塞。这种情况会导致程序无法正常退出。
// 验证消费者线程在生产者退出后是否会因死锁而卡住。

#include <gtest/gtest.h>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <future>
#include <chrono>
#include <iostream>

// 全局共享资源
std::queue<int> buffer; // 缓冲区队列
const unsigned int max_size = 10; // 缓冲区最大容量
std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量

// 生产者函数
void producer() {
    for (int i = 0; i < 5; ++i) { // 假设生产 5 个任务
        std::unique_lock<std::mutex> lock(mtx); // 加锁
        cv.wait(lock, [] { return buffer.size() < max_size; }); // 等待缓冲区有空间
        buffer.push(i); // 生产任务
        std::cout << "Produced: " << i << std::endl;
        cv.notify_one(); // 通知消费者
    }
    // 生产者完成后直接退出，没有通知消费者，可能引发死锁
}

// 消费者函数
void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx); // 加锁
        cv.wait(lock, [] { return !buffer.empty(); }); // 等待缓冲区有数据
        int item = buffer.front(); // 获取任务
        buffer.pop(); // 消费任务
        std::cout << "Consumed: " << item << std::endl;
        cv.notify_one(); // 通知生产者
    }
}

// 测试消费者在生产者退出后是否会死锁
TEST(ProducerConsumerDeadlockTest, ConsumerDeadlock) {
    // 启动生产者线程
    std::thread prod(producer);

    // 使用 std::future 捕获消费者线程的执行状态
    auto consumer_future = std::async(std::launch::async, consumer);

    // 等待生产者线程完成
    prod.join();

    // 设置消费者超时时间为 2 秒
    auto status = consumer_future.wait_for(std::chrono::seconds(2));

    // 如果消费者线程未在 2 秒内完成，判定为死锁
    EXPECT_EQ(status, std::future_status::ready) << "消费者线程陷入死锁！";

    // 如果消费者线程未死锁，获取其结果以确保清理
    if (status == std::future_status::ready) {
        consumer_future.get();
    }
}